﻿using System;
using System.IO;
using System.Collections.Generic;

namespace FileCopier
{
    public enum LogType
    {
        NormalLog,
        Warning,
        Error
    };

    public enum CopyConflictResolutionType
    {
        Replace,
        DontCopy,
        Rename
    }

    public class CopyConflictResolution
    {
        public CopyConflictResolution()
        {
        }

        public CopyConflictResolution(CopyConflictResolution res)
        {
            this.Resolution = res.Resolution;
            this.UseAlways = res.UseAlways;
        }

        public CopyConflictResolutionType Resolution;
        public bool UseAlways;
    }

    public interface ILoggger
    {
        void AddStringToLog(String Text, LogType type = LogType.NormalLog);
        //void CurrentFileProgress();
        //void TotalProgress();
        CopyConflictResolution CopyConflict(FileInfo Src, FileInfo Dst);

    }

    public class FileCopier
    {
        static private void CopyFile(String OriginalFile, String DestinationFolder)
        {

        }

        static public void CopyFiles(List<String> FilesList, String DestinationFolder, Settings.SyncFolder.SyncType OperationType, Settings.SyncFolder.CopyType CType, ILoggger Logger = null, String Template = null)
        {
            if (!Directory.Exists(DestinationFolder))
            {
                throw new DirectoryNotFoundException();
            }

            foreach (String name in FilesList)
            {
                FileInfo finfo = new FileInfo(name);
                String DestDir;

                bool Overwrite = false;
                switch (OperationType)
                {
                    case Settings.SyncFolder.SyncType.ToSubfolderCreationDate:
                        DestDir = System.IO.Path.Combine(DestinationFolder, finfo.CreationTime.ToString(Template)); break;
                    case Settings.SyncFolder.SyncType.ToSubfolderModifyDate:
                        DestDir = System.IO.Path.Combine(DestinationFolder, finfo.LastWriteTime.ToString(Template)); break;
                    case Settings.SyncFolder.SyncType.ToSubFolderSyncDate:
                        DestDir = System.IO.Path.Combine(DestinationFolder, DateTime.Today.ToString(Template)); break;
                    default: DestDir = DestinationFolder; break;
                }

                if (!Directory.Exists(DestDir))
                {
                    try
                    {
                        Directory.CreateDirectory(DestDir);
                    }
                    catch (Exception e)
                    {
                        if (Logger != null)
                        {
                            Logger.AddStringToLog("Невозможно создать папку: " + DestDir + " \n " + e.ToString(), LogType.Error);
                        }
                        continue;
                    }
                }
                String Dest = System.IO.Path.Combine(DestDir, finfo.Name);
                if (Logger != null)
                {
                    Logger.AddStringToLog("Копирование файла: " + name + "\n    в" + Dest);
                }
                if (File.Exists(Dest))
                {
                    FileInfo dinfo = new FileInfo(Dest);
                    switch (CType)
                    {
                        case Settings.SyncFolder.CopyType.CopyNewAndChangedFiles:
                            {
                                if (!IsFileWasChanged(Logger, finfo, dinfo)) continue;
                                if (Logger != null)
                                {
                                    CopyConflictResolution resl = Logger.CopyConflict(finfo, dinfo);

                                    switch (resl.Resolution)
                                    {
                                        case CopyConflictResolutionType.DontCopy:
                                            {
                                                continue;
                                            }
                                        case CopyConflictResolutionType.Rename:
                                            {


                                            }break;
                                        case CopyConflictResolutionType.Replace:
                                            {
                                                Logger.AddStringToLog("Перезаписываем файл...");
                                                Overwrite = true;
                                            }break;
                                    }
                                }
                                else
                                {
                                    throw new Exception("Logger is not found!");
                                }

                            } break;
                        case Settings.SyncFolder.CopyType.CopyNewAndChangedFilesNoReplaceNotify:
                            {
                                if(!IsFileWasChanged(Logger, finfo, dinfo)) continue;
                                Overwrite = true;
                            } break;
                        case Settings.SyncFolder.CopyType.CopyOnlyNewFiles:
                        default:
                            {
                                Overwrite = false;
                                if (Logger != null)
                                {
                                    Logger.AddStringToLog("    Файл уже существует. Замена не нужна.\n", LogType.Warning);
                                }
                                continue;
                            }
                    }

                }
                try
                {
                    finfo.CopyTo(Dest, Overwrite);
                    FileInfo dinfo = new FileInfo(Dest);
                    dinfo.CreationTime = finfo.CreationTime;
                    dinfo.LastWriteTime = finfo.LastWriteTime;
                }
                catch (Exception e)
                {
                    if (Logger != null)
                    {
                        Logger.AddStringToLog("Невозможно скопировать файл \n " + e.ToString(), LogType.Error);
                    }
                    continue;
                }
            }


        }

        private static bool IsFileWasChanged(ILoggger Logger, FileInfo finfo, FileInfo dinfo)
        {
            if (finfo.Length == dinfo.Length &&
                finfo.CreationTime == dinfo.CreationTime &&
                finfo.LastWriteTime == dinfo.LastWriteTime)
            {
                if (Logger != null)
                {
                    Logger.AddStringToLog("    Файл не изменился.\n", LogType.Warning);
                }
                return false; ;
            }
            return true;
        }



    }

}